
package com.sun.showcase.biz.mall.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sun.showcase.biz.basic.service.BaseseCodingRuleService;
import com.sun.showcase.biz.basic.service.UserInfoService;
import com.sun.showcase.biz.exception.BusinessException;
import com.sun.showcase.biz.mall.dao.OrderReturnDao;
import com.sun.showcase.biz.mall.service.MemberBillService;
import com.sun.showcase.biz.mall.service.MemberService;
import com.sun.showcase.biz.mall.service.OrderGoodsService;
import com.sun.showcase.biz.mall.service.OrderReturnService;
import com.sun.showcase.biz.mall.service.OrderService;
import com.sun.showcase.biz.mall.service.PlatformConfigService;
import com.sun.showcase.biz.mall.service.ShopBillService;
import com.sun.showcase.client.domain.mall.Member;
import com.sun.showcase.client.domain.mall.Order;
import com.sun.showcase.client.domain.mall.OrderGoods;
import com.sun.showcase.client.domain.mall.OrderReturn;
import com.sun.showcase.client.domain.mall.PlatformConfig;
import com.sun.showcase.client.query.mall.MemberBillQuery;
import com.sun.showcase.client.query.mall.OrderGoodsQuery;
import com.sun.showcase.client.query.mall.OrderReturnQuery;
import com.sun.showcase.client.query.mall.ShopBillQuery;
import com.sun.showcase.client.vo.order.ReturnOrderEntity;
import com.sun.showcase.pojo.DataGrid;
import com.sun.showcase.pojo.Pager;
import com.sun.showcase.utils.ArithUtil;
import com.sun.showcase.utils.DateUtil;
import com.sun.showcase.utils.ExecuteResult;
import com.sun.showcase.utils.StringConstant;
import com.sun.showcase.utils.UuidUtil;
import com.sun.showcase.utils.ValidatorUtils;
@Service("orderReturnService")
@Transactional
public class OrderReturnServiceImpl implements OrderReturnService{
	@Autowired
	private OrderReturnDao orderReturnDao;
	@Autowired
	private OrderGoodsService orderGoodsService;
	@Autowired
	private BaseseCodingRuleService baseseCodingRuleService;
	@Autowired
	private OrderService orderService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private WxPayService wxPayService;
	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private ShopBillService shopBillService;
	@Autowired
	private PlatformConfigService platformConfigService;
	@Autowired
	private MemberBillService memberBillService;
	public void setOrderReturnDao(OrderReturnDao dao) {
		this.orderReturnDao = dao;
	}

	public DataGrid datagrid(OrderReturnQuery orderReturnQuery) {
		DataGrid j = new DataGrid();
		Pager<OrderReturn> pager  = find(orderReturnQuery);
		j.setRows(getQuerysFromEntitys(pager.getRecords()));
		j.setTotal(pager.getTotalRecords());
		return j;
	}

	private List<OrderReturnQuery> getQuerysFromEntitys(List<OrderReturn> orderReturns) {
		List<OrderReturnQuery> orderReturnQuerys = new ArrayList<OrderReturnQuery>();
		if (orderReturns != null && orderReturns.size() > 0) {
			for (OrderReturn tb : orderReturns) {
				OrderReturnQuery b = new OrderReturnQuery();
				BeanUtils.copyProperties(tb, b);
				orderReturnQuerys.add(b);
			}
		}
		return orderReturnQuerys;
	}

	private Pager<OrderReturn> find(OrderReturnQuery orderReturnQuery) {
		Page<OrderReturn> page = PageHelper.startPage(orderReturnQuery.getPage().intValue(), orderReturnQuery.getRows().intValue());
		List<OrderReturn> list = orderReturnDao.findList(orderReturnQuery);
		Pager<OrderReturn> pager = new Pager<OrderReturn>();
		pager.setRecords(list);
		pager.setTotalRecords(page.getTotal());
		return  pager;
		
	}
	


	public OrderReturn add(OrderReturnQuery orderReturnQuery) {
		OrderReturn t = new OrderReturn();
		BeanUtils.copyProperties(orderReturnQuery, t);
		t.setStatus(StringConstant.ZERO);
		t.setCreateDate(new Date());
	    t.setId(UuidUtil.get32UUID());
		orderReturnDao.save(t);
		orderReturnQuery.setId(t.getId());
		return t;
		
	}

	public void update(OrderReturnQuery orderReturnQuery) {
		OrderReturn t = orderReturnDao.getById(orderReturnQuery.getId());
	    if(t != null) {
	    	BeanUtils.copyProperties(orderReturnQuery, t);
	    	orderReturnDao.update(t);
		}
	}
	
	/**
	 * 根据条件更新部分字段   新建一个query封装需要更新的字段
	 * searchMap封装更新条件
	 * */
	public void updatePart(OrderReturnQuery orderReturnQuery) {
	    orderReturnDao.updatePart(orderReturnQuery);
	}

	public void delete(java.lang.String[] ids) {
		orderReturnDao.deleteAc(ids);
	}
	
	//逻辑删除 更新状态位
	public void deletePt(java.lang.String[] ids) {
		orderReturnDao.deletePt(ids);
	}

	public OrderReturn get(OrderReturnQuery orderReturnQuery) {
		return orderReturnDao.getById(orderReturnQuery.getId());
	}

	public OrderReturn get(String id) {
		return orderReturnDao.getById(id);
	}

	
	public List<OrderReturnQuery> listAll(OrderReturnQuery orderReturnQuery) {
	    List<OrderReturn> list = orderReturnDao.findList(orderReturnQuery);
		List<OrderReturnQuery> listQuery =getQuerysFromEntitys(list) ;
		return listQuery;
	}
	private synchronized String getNextCode() {
		return baseseCodingRuleService.getNextCodeById(3L);
	}
	@Override
	public ExecuteResult<String> save(ReturnOrderEntity entity) {
		ValidatorUtils.validate(entity);
		ExecuteResult<String> exe = new ExecuteResult<String>();
		Member mem = memberService.get(entity.getUserId());
		if(mem == null) {
			exe.addErrorMessage("无效用户");
			return exe;
		}
		
		OrderGoods og = orderGoodsService.get(entity.getOrderGoodsId());
		if(og == null) {
			exe.addErrorMessage("无效订单");
			return exe;
		}
		//一个订单的一种商品目前只允许退一次。
		if(og.getReturnNum()!=null && og.getReturnNum()>0) {
			exe.addErrorMessage("不可重复退货");
			return exe;
		}
		Order order = orderService.get(og.getOrderId());
		if(order == null || !"3".equals(order.getOrderStateCode())) {
			exe.addErrorMessage("无效订单");
			return exe;
		}
		PlatformConfig conf = platformConfigService.get();
		if(conf != null && DateUtil.getDaySub(order.getOrderCompleteDate(), new Date())>=conf.getOrderReturnDay()) {
			exe.addErrorMessage("已超时，不可退单");
			return exe;
		}
		OrderReturnQuery r = new OrderReturnQuery();
		r.setReturnNo(this.getNextCode());
		r.setOrderId(og.getOrderId());
		r.setOrderNo(order.getOrderNo());
		r.setGoodsId(og.getGoodsId());
		r.setGoodsName(og.getGoodsName());
		r.setMainPictureAddress(og.getMainPictureAddress());
		r.setSkuId(og.getSkuId());
		r.setSkuName(og.getSkuName());
		r.setUserId(mem.getId());
		r.setUserName(mem.getNickName());
		r.setReturnName(entity.getReturnName());
		r.setReturnNum(og.getBuyNum());//暂时，全退
		r.setReturnPhone(entity.getReturnPhone());
		r.setExpressOrderCode(entity.getExpressOrderCode());
		r.setReason(entity.getReason());
		this.add(r);
		//更新订单商品退货数量
		orderGoodsService.updateReturnNum(og.getId(), og.getBuyNum());
		exe.setSuccessMessage("申请提交成功！");
		return exe;
	}

	@Override
	public ExecuteResult<String> updateStatus(String id, String status) {
		ExecuteResult<String> exe = new ExecuteResult<String>();
		OrderReturn r = this.get(id);
		if(r == null) {
			exe.addErrorMessage("无效操作");
			return exe;
		}
		OrderReturnQuery up = new OrderReturnQuery();
		up.getSearchMap().put("id", id);
		up.setStatus(status);
		if(("1".equals(status) ||"3".equals(status)) && "0".equals(r.getStatus())) {
			up.setApplyDate(new Date());
		}else if(("2".equals(status) ||"4".equals(status)) && "1".equals(r.getStatus())) {
			Order order = orderService.get(r.getOrderId());
			OrderGoodsQuery ogq = new OrderGoodsQuery();
			ogq.setOrderId(order.getId());
			ogq.setGoodsId(r.getGoodsId());
			List<OrderGoodsQuery> list = orderGoodsService.listAll(ogq);
			if(list.size() !=1) {
				exe.addErrorMessage("微信退款失败,订单商品异常");
				return exe;
			}
			ogq = list.get(0);
			up.setReturnAmount(ArithUtil.mul(ogq.getDealPrice(), ogq.getBuyNum()));
			//确认退款
			if("2".equals(status)) {
				PlatformConfig conf = platformConfigService.get();
				if(conf != null && DateUtil.getDaySub(order.getOrderCompleteDate(), new Date())>=conf.getOrderReturnDay()) {
					exe.addErrorMessage("已超时，不可退单");
					return exe;
				}
				if("0".equals(order.getSettleStatus())) {
					//未结算订单，更新订单的可结算金额
					orderService.updateSettleAmount(order.getId(), up.getReturnAmount()*-1);
				}else if("1".equals(order.getSettleStatus())) {
					//已结算订单，扣除余额，可能造成负数
					//更新店主余额
					userInfoService.updateBalance(order.getShopOwnerId(), up.getReturnAmount()*-1);
					//增加账单
					ShopBillQuery ad = new ShopBillQuery();
		    		ad.setBussinessId(r.getReturnNo());
		    		ad.setAmount(up.getReturnAmount());
		    		ad.setType(StringConstant.ONE);
		    		ad.setStatus(StringConstant.ONE);
		    		ad.setUserId(order.getShopOwnerId());
		    		ad.setUserName(order.getShopOwnerName());
		    		ad.setRemark("订单退款");
		    		shopBillService.add(ad);
		    		//FIXME 或者改为订单如果结算了，就不允许线上退款了, 因为一旦结算了，商家有可能吧钱提现了。
				}
				//查看是否有返利，如果有，怎扣除返利
				MemberBillQuery mbq = new MemberBillQuery();
				mbq.setBussinessId(order.getId());
				mbq.setType("0");//收入
				List<MemberBillQuery> mbList = memberBillService.listAll(mbq);
				for(MemberBillQuery mq : mbList) {
					//扣除返利
					memberService.updateBalance(mq.getUserId(), 0D, -1*mq.getAmount());
					// 会员账单
					MemberBillQuery mb = new MemberBillQuery();
					mb.setType("1");
					mb.setStatus("1");
					mb.setAmount(mq.getAmount());
					mb.setRemark(mq.getRemark()+"-退款扣除");
					mb.setUserId(mq.getUserId());
					mb.setUserName(mq.getUserName());
					mb.setBussinessId(mq.getId());
					memberBillService.add(mb);
				}
				if("0".equals(order.getPayType())) {
					//微信支付  线上退款
					WxPayRefundRequest req = new WxPayRefundRequest();
					try {
						req.setTransactionId(order.getPayOrderNo());
						req.setOutRefundNo(r.getReturnNo());
						req.setTotalFee(BaseWxPayRequest.yuanToFen(up.getReturnAmount().toString()));
						req.setRefundFee(req.getTotalFee());
						wxPayService.refund(req);
					} catch (WxPayException e) {
						exe.addErrorMessage("微信退款失败,"+e.getMessage());
						throw new BusinessException("微信退款失败");
					}
				}
				
			}
			up.setDealDate(new Date());
		}else {
			exe.addErrorMessage("无效操作");
			return exe;
		}
		this.updatePart(up);
		return exe;
	}
	
	
}
